{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<a name=\"top\"></a><img src=\"./source/SpinalHDL.png\" alt=\"SpinalHDL based on Scala\" style=\"width:320px;\" />"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "  Before running Spinal HDL code, be sure to load Spinal HDL Libraries  \n",
    "**Note** : This may be a little slow when the first time load, please wait a moment to download Lib from remote.)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "val path = System.getProperty(\"user.dir\") + \"/source/load-spinal.sc\"\n",
    "interp.load.module(ammonite.ops.Path(java.nio.file.FileSystems.getDefault().getPath(path)))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Sequential Logic\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "There is 4 ways to instantiate a **register**: \n",
    "\n",
    "Syntax | Description\n",
    "-|-\n",
    "Reg(type : Data) |Register of the given type\n",
    "RegInit(resetValue : Data)|Register loaded with the given resetValue when a reset occurs\n",
    "RegNext(nextValue : Data) |Register that samples the given nextValue each cycle\n",
    "RegNextWhen(nextValue : Data, cond : Bool)|Register that samples the given nextValue when a condition occurs"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "class Top extends Component{ \n",
    "val cond = in Bool()\n",
    "//UInt register of 4 bits\n",
    "val reg1 = Reg(UInt(4 bit))\n",
    "\n",
    "//Register that samples reg1 each cycle\n",
    "val reg2 = RegNext(reg1 + 1)\n",
    "\n",
    "//UInt register of 4 bits initialized with 0 when the reset occurs\n",
    "val reg3 = RegInit(U\"0000\")\n",
    "reg3 := reg2\n",
    "when(reg2 === 5){\n",
    "  reg3 := 0xF\n",
    "}\n",
    "\n",
    "//Register that samples reg3 when cond is True\n",
    "val reg4 = RegNextWhen(reg3,cond)\n",
    "}\n",
    "showRtl(new Top)"
   ]
  },
  {
   "attachments": {
    "image.png": {
     "image/png": "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+sgefvhhu/nmm+2RRy7a1l166aXJ8ZVX4n+mfuCD4IorrrCzZ8/WTzz5KTIBjvtahWICEuDFbHRFBERABEoJnDlzJvGPftddd5XG00URaIOABHgbVJWnCIjATBBAQ77mmmtsxYoVjdb3ySefTFY/azrfRgupzBadgAT4ojeBCiACIiACZvfcc4/hlpXftddea0899ZTRFa8gAkUEJMCLyOi8CIiACAwgsHz5cjt37lxitDYg6sDLbsR27Ngxe/zxx+2tt2KvrwOzUIQZIyABPmMNruqKgAg0R4Au7qVLl9pLLzHNuZmAQdymTZts7969hpGcgggUEZAALyKj8yIgAiIwgABd3Fu2bEm6v5999uLCWwjexx57bOhpYPfff38yfer48UFuwwcUUJenmoAE+FQ3ryonAiLQNgE0ZozZDh06lI1h33TTTYZlejyNbO3atVkcxrpffz1/YTXS8WHwwAMPqCu97Qac4Py1GtkEN56KLgIi0A0CCNyybvRB1zFYi8Pdd99t/BREoIiABHgRGZ0XAREQgYDAN77xjWQN8ODUou3inUxBBJYIgQiIgAiIQCEBFvc+Uni1GxeOmtk0LUK+28x2gXbVqlXJrwuYT548acFa5Lemy54uatGkgS8qft1cBESg4wRYSrPrYRLKOBRDehrU21CMTgK8mI2uiIAIiMCHZnaDmd3REIoHzGx5mhcD398aMV/60g+PmEfXkk/CB0knyqgu9K49uiqPCIjANBP4QzP7sbSCc2b2B9Nc2RHqtooe9BHSt5kU4c2H3aIHaeCL3gQqgAiIgAiIQESAngVZ6kVQ4kPNA4+J6FgEREAEREAEJoCABPgENJKKKAIiIAIiIAIxAQnwmIiORUAEREAERGACCEiAT0AjqYgiIAIiIAIiEBOQAI+J6FgEREAEREAEJoCABPgENJKKKAIiIAIiIAIxAQnwmIiORUAEREAERGACCEiAT0AjqYgiIAIiIAIiEBOQAI+J6FgEREAEREAEJoCABPgENJKKKAIiIAIiIAIxAQnwmIiORUAEREAERGACCEiAT0AjqYgiIAIiIAIiEBOQAI+J6FgEREAEREAEJoCABPgENJKKKAIiIAIiIAIxAQnwmIiORUAEREAERGACCGg98AloJBVRBERgagj8XzP707Q2P5iaWqkiIiACIiACIiACIiACIiACIiACIiACIiACIiACIiACIiACIiACIiACIiACIiACIiACIiACIiACIiACs0Xgh2aruqqtCIiACEwsgSvN7AUz65nZ/5jYWqjgjRHQPPDGUCojERABEWiVwHIzu6rVOyjziSIgAT5RzaXCioAIiIAIiIAIiIAIiIAI1CFwqZk9lf5+Ke3K5pjz15nZyfQcXdx+3vP3tFzLu068sjweCfL2PO72zLUVAREQAREQAREoJhAKYQSqBxe8LlA9ngtxP47TrPYMAuFdlAdR4/sEybU7iwTUhT6Lra46i4AIjELgZTN7Ms0A4fygmb1hZs+n5z4ys0NmtsbMVqQ/9t8ObvpWqrFzqkoeQVLtisAFAhLgehJEQAREoB6Bd8zsfJoEAY1wfs3MENwezqY7GJ6x/56ZPZRq0R7Ht1Xy8LjaikBGQAI8Q6EdERABERiawHw0Rn3KzObMbJWZvW9mO9KcOc8Y9s05dyrLIye6Ts06AQnwWX8CVH8REIEmCKw1syU5v2fTzOkyZ8wbjZwu+GNm5uPdfv9BeXg8bUUgISABrgdBBERABIYncCYd/76tYhZo43ea2dNmdm2apm4eFW+laNNOQAJ82ltY9RMBEWiTgBus7Yk0aizGvxhMMdsYFOKytGvdjdqq5EFyH0t3wR9kqV0REAEREAEREIEiAj4dzKeHhfEY0/b52XnzvOkuD6/H3efkNSiPOE5eHmGZtC8CIiACIiACIiACIiACIiACIiACIiACIiACIiACIiACIiACIiACIiACIiACIiACIiACIiACIiACIiACIiACIiACIiACIiACIiACIiACIiACIiACIiACIiACIiACIjBGAv8f8vQ7nr1UzZ8AAAAASUVORK5CYII="
    }
   },
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "The code above will infer the following logic:\n",
    "![image.png](attachment:image.png)\n",
    "Also, RegNext is an abstraction which is built over the Reg syntax. The two following sequences of code are strictly equivalent:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "class Top extends Component{\n",
    "  //Standard way\n",
    "  val something = Bool\n",
    "  val value = Reg(Bool)\n",
    "  value := something\n",
    "\n",
    "  //Short way\n",
    "  val something1 = Bool\n",
    "  val value1 = RegNext(something)\n",
    "}\n",
    "showRtl(new Top)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### Reset Value\n",
    "In addition to the RegInit(value : Data) syntax which directly creates the register with a reset value, you can also set the reset value by calling the init(value : Data) function on the register.\n",
    "\n",
    "If you have a register containing a Bundle, you can use the init function on each element of the Bundle."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "case class ValidRGB() extends Bundle{\n",
    "  val valid = Bool\n",
    "  val r,g,b = UInt(8 bits)\n",
    "}\n",
    "\n",
    "class Top extends Component{\n",
    "  val reg = Reg(ValidRGB())\n",
    "  reg.valid init(False)  //Only the valid of that register bundle will have an reset value.\n",
    "}\n",
    "showRtl(new Top)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### Initialization value for simulation purposes\n",
    "For registers that don’t need a reset value in RTL, but need an initialization value for simulation (to avoid x-propagation), you can ask for an random initialization value by calling the randBoot() function."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "class Top extends Component{\n",
    "  val reg1 = Reg(UInt(4 bit)) randBoot()\n",
    "}\n",
    "showRtl(new Top)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "##  [RAM/ROM](https://spinalhdl.github.io/SpinalDoc-RTD/SpinalHDL/Sequential%20logic/memory.html)\n",
    "To create a memory in SpinalHDL, the Mem class should be used. It allows you to define a memory and add read and write ports to it."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "class Top extends Component{\n",
    " val io = new Bundle{\n",
    "        val writeValid = in Bool()\n",
    "        val writeAddress = in UInt(8 bits)\n",
    "        val writeData = in Bits(32 bits)\n",
    "        val readValid = in Bool()\n",
    "        val readAddress = in UInt(8 bits)\n",
    "        val readData = out Bits(32 bits)\n",
    "    }\n",
    " val mem = Mem(Bits(32 bits),wordCount = 256)\n",
    " mem.write(\n",
    "  enable  = io.writeValid,\n",
    "  address = io.writeAddress,\n",
    "  data    = io.writeData\n",
    " )\n",
    "\n",
    " io.readData := mem.readSync(\n",
    "  enable  = io.readValid,\n",
    "  address = io.readAddress\n",
    " )\n",
    " }\n",
    "showRtl(new Top)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "As for Read under write policy, to use this feature you need to enable the automatic memory blackboxing, because there is no universal VHDL/Verilog language template to infer mixed width ram.\n",
    "#### Blackboxing policy\n",
    "There are multiple policies that you can use to select which memory you want to blackbox and also what to do when the blackboxing is not feasible:\n",
    "\n",
    "Kinds | Description\n",
    "-|-\n",
    "blackboxAll | Blackbox all memory.<br> Throw an error on unblackboxable memory  \n",
    "blackboxAllWhatsYouCan | Blackbox all memory that is blackboxable\n",
    "blackboxRequestedAndUninferable | Blackbox memory specified by the user and memory that is known to be uninferable (mixed width, …). <br>  Throw an error on unblackboxable memory  \n",
    "blackboxOnlyIfRequested | Blackbox memory specified by the user <br>  Throw an error on unblackboxable memory"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "SpinalConfig(targetDirectory=\"rtl/\")\n",
    "    .addStandardMemBlackboxing(blackboxAll)\n",
    "    .generateVerilog(new Top)\n",
    "scala.io.Source.fromFile(\"rtl/TopTopLevel.v\").mkString"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "To explicitly set a memory to be blackboxed, you can use its `generateAsBlackBox` function."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "import spinal.lib.graphic._\n",
    "class Top extends Component{\n",
    "    val io = new Bundle{\n",
    "        val writeValid = in Bool()\n",
    "        val writeAddress = in UInt(8 bits)\n",
    "        val writeData = in(Rgb(RgbConfig(8,8,8)))\n",
    "        val readValid = in Bool()\n",
    "        val readAddress = in UInt(8 bits)\n",
    "        val readData = out(Rgb(RgbConfig(8,8,8)))\n",
    "    }\n",
    "    \n",
    " val mem = Mem(Rgb(RgbConfig(8,8,8)),1024)\n",
    "    \n",
    " mem.generateAsBlackBox() // explicitly set a memory to be blackboxed\n",
    "   \n",
    " mem.write(\n",
    "  enable  = io.writeValid,\n",
    "  address = io.writeAddress,\n",
    "  data    = io.writeData\n",
    " )\n",
    "\n",
    " io.readData := mem.readSync(\n",
    "  enable  = io.readValid,\n",
    "  address = io.readAddress\n",
    " )\n",
    "}\n",
    "showRtl(new Top)    "
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "As you can see, blackboxes have a technology parameter. To set it you can use the setTechnology function on the corresponding memory. There are currently 4 kinds of technogy possible:\n",
    "- auto\n",
    "- ramBlock\n",
    "- distributedLut\n",
    "- registerFile\n",
    "\n",
    "```scala\n",
    "class Top extends Component{\n",
    "  ...\n",
    "  val mem = Mem(Bits(32 bits),wordCount = 256)\n",
    "  mem.setTechnology(tech=ramBlock)\n",
    "  mem.generateAsBlackBox()\n",
    "  ...\n",
    "}\n",
    "```"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Scala",
   "language": "scala",
   "name": "scala"
  },
  "language_info": {
   "codemirror_mode": "text/x-scala",
   "file_extension": ".scala",
   "mimetype": "text/x-scala",
   "name": "scala",
   "nbconvert_exporter": "script",
   "version": "2.12.8"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
